home *** CD-ROM | disk | FTP | other *** search
Lex Description | 1996-12-29 | 13.2 KB | 629 lines |
- %{
- #include "txt2midi.h"
- #include "midiread.hpp"
- #include "math.h"
- #include <string.h>
- #include <ctype.h>
- #include <assert.h>
-
- #ifdef __MSDOS__
- #define STRICMP stricmp
- #else
- #define STRICMP strcmp
- #endif
-
- extern int yyerror( char* msg );
-
- struct lexstate
- {
- int index; // file
- long linenr;
- YY_BUFFER_STATE buffer;
-
- lexstate* save;
- };
-
- void init_lexstate(lexstate* l)
- {
- assert(l != 0);
- l->index = 0;
- l->linenr = 1;
- l->buffer = 0;
- l->save = 0;
- }
-
- lexstate *src = 0;
-
- #define MAXNAMES 10
- char filename[MAXNAMES][128];
- int filenames = 0;
-
- int noteval(char* s);
- void includefile(char* name);
-
- #undef YY_DECL
- #define YY_DECL int ylex(void)
-
- %}
-
- hexdigit [a-fA-F0-9]
- decdigit [0-9]
- ws [ \t]
- sign [+-]
- char (\\[Xx]{hexdigit}{hexdigit}|\\.|.)
- float {decdigit}+("."{decdigit}+)?
- eow [^a-zA-Z0-9_]
-
- %start MIDI CMNT PROGRAM
-
- %%
-
- if ( yy_start == 0 ) BEGIN MIDI;
-
- <MIDI>\"{char}*\" {
- char* s = (char*)yytext+1, *t;
-
- t = (char*)yytext;
- yyleng = 0;
- while (*s != '"')
- {
- if (*s == '\\')
- {
- s++;
- if (*s == 'x' || *s == 'X')
- {
- int val = 0;
-
- s++;
- if (isdigit(*s))
- val = *s - '0';
- else
- val = toupper(*s) - 'A'+10;
- s++;
- if (isdigit(*s))
- val = val * 16 + (*s - '0');
- else
- val = val * 16 + (toupper(*s) - 'A'+10);
- s++;
- *t++ = val;
- }
- else
- {
- *t++ = *s++;
- }
- }
- else
- *t++ = *s++;
- yyleng++;
- }
- *t = 0;
- return(_TEXT);
- }
-
- <MIDI>"#"{ws}*include{ws}+"<".+">".*$ {
- char* s = strchr((char*)yytext, '<');
-
- if (s)
- strcpy((char*)yytext, s+1);
- s = strchr((char*)yytext, '>');
- if (s)
- *s = 0;
- includefile((char*)yytext);
- }
-
-
- <MIDI>\/\/.*$ ; /* comment */
-
- <MIDI>[ \t] ; /* blanks */
-
- <MIDI>\n src->linenr++;
-
- <MIDI>[CDFGAcdfga]("#"|"is")?"-"?1?[0-9]? |
- <MIDI>[BHDEGbhdeg]("b"|"es")?"-"?1?[0-9]? |
- <MIDI>[AaEe]s?"-"?1?[0-9] |
- <MIDI>[BbHh]"-"?1?[0-9] {
- yylval.longv = noteval((char*)yytext);
- return(_NOTE);
- }
-
- <MIDI>{sign}?"$"{hexdigit}+ {
- if (yytext[0] == '-' || yytext[0] == '+')
- {
- yylval.longv = strtol(strchr((char*)yytext, '$')+1, 0, 16);
- if (yytext[0] == '-')
- yylval.longv = -yylval.longv;
- return(_SIGNEDNUMBER);
- }
- else
- {
- yylval.longv = strtol(strchr((char*)yytext, '$')+1, 0, 16);
- return(_NUMBER);
- }
- }
-
- <MIDI>{sign}?"0[xX]"{hexdigit}+ {
- yylval.longv = strtol((char*)yytext+2, 0, 16);
- return(_NUMBER);
- if (yytext[0] == '-' || yytext[0] == '+')
- {
- yylval.longv = -strtol(strchr((char*)yytext, '0'), 0, 16);
- return(_SIGNEDNUMBER);
- }
- else
- {
- yylval.longv = strtol(strchr((char*)yytext, '0'), 0, 16);
- return(_NUMBER);
- }
- }
-
- <MIDI>{sign}?0[0-7]* {
- if (yytext[0] == '-' || yytext[0] == '+')
- {
- yylval.longv = -strtol(strchr((char*)yytext, '0'), 0, 8);
- return(_SIGNEDNUMBER);
- }
- else
- {
- yylval.longv = strtol(strchr((char*)yytext, '0'), 0, 8);
- return(_NUMBER);
- }
- }
-
- <MIDI>{sign}?[0-9]+ {
- if (yytext[0] == '-' || yytext[0] == '+')
- {
- yylval.longv = strtol((char*)yytext, 0, 10);
- return(_SIGNEDNUMBER);
- }
- else
- {
- yylval.longv = strtol((char*)yytext, 0, 10);
- return(_NUMBER);
- }
- }
-
- <MIDI>"*"|"x" return(_TIMES);
-
- <MIDI>"/" return(_DIV);
-
- <MIDI>";" return(_SEP);
-
- <MIDI>"." return(_ENDTACT);
-
- <MIDI>"(" return('(');
-
- <MIDI>")" return(')');
-
- <MIDI>":" return(':');
-
- <MIDI>"[" return('[');
-
- <MIDI>"]" return(']');
-
- <MIDI>[Mm][Tt]hd return(_HEAD);
-
- <MIDI>[Mm][Tt]rk return(_TRACK);
-
- <MIDI>[Tt]empo return(_TEMPO);
-
- <MIDI>[Bb]eats{ws}+{float} {
- char* s = (char*)yytext + 5;
-
- yylval.floatv = atof(s);
- return(_BEATS);
- }
-
- <MIDI>[Uu]nits?/{eow} return(_UNIT);
-
- <MIDI>[Ee][Nn][Dd]/{eow} return(_END);
-
- <MIDI>[Ss]eq[Nn]umber/{eow} return(_SEQNUMBER);
-
- <MIDI>[Tt]ext/{eow} return(_GENERAL_TEXT);
-
- <MIDI>[Cc]opyright/{eow} return(_COPYRIGHT);
-
- <MIDI>[Tt]rackname/{eow} return(_TRACKNAME);
-
- <MIDI>[Ii]nstrument/{eow} return(_INSTRUMENT);
-
- <MIDI>[Ll]yric/{eow} return(_LYRIC);
-
- <MIDI>[Mm]arker/{eow} return(_MARKER);
-
- <MIDI>[Kk]ey/{eow} return(_KEY);
-
- <MIDI>[Cc]ue[Pp]oint/{eow} return(_CUEPOINT);
-
- <MIDI>[Pp]refix[Cc]hannel/{eow} return(_PREFIXCHANNEL);
-
- <MIDI>[Pp]refix[Pp]ort/{eow} return(_PREFIXPORT);
-
- <MIDI>[Ss][Mm][Pp][Tt][Ee][Oo]fs/{eow} return(_SMPTEOFS);
-
- <MIDI>[Tt]act/{eow} return(_TACT);
-
- <MIDI>[Ee]vent/{eow} return(_EVENT);
-
- <MIDI>[Mm]eta[Ee]vent/{eow} return(_METAEVENT);
-
- <MIDI>[Ss]ys[Ee]vent/{eow} return(_SYSEVENT);
-
- <MIDI>[Pp]rogram/{eow} { BEGIN PROGRAM; return(_PROGRAM); }
-
- <MIDI>[Vv]ersion/{eow} return(_VERSION);
-
- <MIDI>[Cc]ontrol/{eow} return(_CONTROL);
-
- <MIDI>[Vv]elocy?on/{eow} return(_VELOCON);
-
- <MIDI>[Vv]elocy?off/{eow} return(_VELOCOFF);
-
- <MIDI>[Tt]ranspose/{eow} return(_TRANSPOSE);
-
- <MIDI>[Oo]n/{eow} return(_ON);
-
- <MIDI>[Oo]ff/{eow} return(_OFF);
-
- <MIDI>[Hh]bank/{eow} return(_HBANK);
-
- <MIDI>[Ll]bank/{eow} return(_LBANK);
-
- <MIDI>[Bb]ank[Aa]/{eow} return(_BANKA);
-
- <MIDI>[Bb]ank[Bb]/{eow} return(_BANKB);
-
- <MIDI>[Bb]ank[Cc]/{eow} return(_BANKC);
-
- <MIDI>[Bb]ank[Dd]/{eow} return(_BANKD);
-
- <MIDI>[Bb]ank[Dd]rums?/{eow} return(_BANKDRUMS);
-
- <MIDI>"+" return(_NOTEON);
-
- <MIDI>"-" return(_NOTEOFF);
-
- <MIDI>[Ll]oop/{eow} return(_LOOP);
-
- <MIDI>[Mm]ute/{eow} return(_MUTE);
-
- <MIDI>[Ss]olo/{eow} return(_SOLO);
-
- <MIDI>[Pp]art/{eow} return(_PART);
-
- <MIDI>[Cc]opy/{eow} return(_COPY);
-
- <MIDI>[Pp]rint/{eow} return(_PRINT);
-
- <MIDI>[Bb]alance/{eow} return(_BALANCE);
-
- <MIDI>[Hh]old/{eow} return(_HOLD);
-
- <MIDI>[Rr]everb/{eow} return(_REVERB);
-
- <MIDI>[Cc]horus/{eow} return(_CHORUS);
-
- <MIDI>[Bb]rightness/{eow} return(_BRIGHTNESS);
-
- <MIDI>[Ee]xpression/{eow} return(_EXPRESSION);
-
- <MIDI>[Pp]itchmodulation/{eow} return(_PITCHMODULATION);
-
- <MIDI>[Ll]eft/{eow} return(_LEFT);
-
- <MIDI>[Rr]ight/{eow} return(_RIGHT);
-
- <MIDI>[Ww]heel/{eow} { yylval.bytev = 1; return(_CHANGE); }
-
- <MIDI>[Bb]reath/{eow} { yylval.bytev = 2; return(_CHANGE); }
-
- <MIDI>[Ff]oot/{eow} { yylval.bytev = 4; return(_CHANGE); }
-
- <MIDI>[Pp]ortamento[Tt]ime/{eow} { yylval.bytev = 5; return(_CHANGE); }
-
- <MIDI>[Pp]ortamento/{eow} { yylval.bytev = 65; return(_CHANGE); }
-
- <MIDI>[Dd]ata/{eow} { yylval.bytev = 6; return(_CHANGE); }
-
- <MIDI>[Vv]olume/{eow} { yylval.bytev = 7; return(_CHANGE); }
-
- <MIDI>[Ss]ustain/{eow} { yylval.bytev = 64; return(_CHANGE); }
-
- <MIDI>[Ss]ostenuto/{eow} { yylval.bytev = 66; return(_CHANGE); }
-
- <MIDI>[Ss]oft[Pp]edal/{eow} { yylval.bytev = 67; return(_CHANGE); }
-
- <MIDI>[Dd]ata[Ii]nc/{eow} { yylval.bytev = 68; return(_CHANGE); }
-
- <MIDI>[Dd]ata[Dd]ec/{eow} { yylval.bytev = 69; return(_CHANGE); }
-
- <MIDI>[Ll]ow[rR][pP][nN]/{eow} { yylval.bytev = 100; return(_CHANGE); }
-
- <MIDI>[Hh]igh[rR][pP][nN]/{eow} { yylval.bytev = 101; return(_CHANGE); }
-
- <MIDI>[Pp]itch[Bb]end[Rr]ange/{eow} { return(_PITCHBENDRANGE); }
-
- <MIDI>[Ll]ocal[Oo]n/{eow} { yylval.longv = 122l + (127l << 8); return(_MODE); }
-
- <MIDI>[Ll]ocal[Oo]ff/{eow} { yylval.longv = 122; return(_MODE); }
-
- <MIDI>[Ss]ilent/{eow} { yylval.longv = 123; return(_MODE); }
-
- <MIDI>[Aa]ll[Nn]otes[Oo]ff/{eow} { yylval.longv = 123; return(_MODE); }
-
- <MIDI>[Oo]mni[Oo]ff/{eow} { yylval.longv = 124; return(_MODE); }
-
- <MIDI>[Oo]mni[Oo]n/{eow} { yylval.longv = 125; return(_MODE); }
-
- <MIDI>[Mm]ono[Oo]n/{eow} { yylval.longv = 126; return(_MODE); }
-
- <MIDI>[Pp]oly[Oo]n/{eow} { yylval.longv = 127; return(_MODE); }
-
- <MIDI>[Ss]ong[Pp]osition/{eow} return(_SONGPOS);
-
- <MIDI>[Ss]ong[Pp]os/{eow} return(_SONGPOS);
-
- <MIDI>[Ss]ong[Ss]elect/{eow} return(_SONGSELECT);
-
- <MIDI>[Tt]une[Rr]equest/{eow} { yylval.bytev = 246; return(_COMMON); }
-
- <MIDI>[Tt]iming[Cc]lock/{eow} { yylval.bytev = 248; return(_COMMON); }
-
- <MIDI>[Ss]tart/{eow} { yylval.bytev = 250; return(_COMMON); }
-
- <MIDI>[Cc]ontinue/{eow} { yylval.bytev = 251; return(_COMMON); }
-
- <MIDI>[Ss]top/{eow} { yylval.bytev = 252; return(_COMMON); }
-
- <MIDI>[Aa]ctive[Ss]ensing/{eow} { yylval.bytev = 254; return(_COMMON); }
-
- <MIDI>[Pp]oly[Aa]fter[Tt]ouch/{eow} return(_POLYAFTERTOUCH);
-
- <MIDI>[Aa]fter[Tt]ouch/{eow} return(_AFTERTOUCH);
-
- <MIDI>[Pp]itch[Bb]end/{eow} return(_PITCHBEND);
-
- <MIDI>[Gg][Mm][Rr]eset/{eow} return(_GMRESET);
-
- <MIDI>[Gg][Ss][Rr]eset/{eow} return(_GSRESET);
-
- <MIDI>[Gg][Ss][Ee]nter/{eow} return(_GSRESET);
-
- <MIDI>[Gg][Ss][Ee]xit/{eow} return(_GSEXIT);
-
- <MIDI>[Xx][Gg][Rr]eset/{eow} return(_XGRESET);
-
- <MIDI>"/*" BEGIN CMNT;
- <MIDI>[A-Za-z_][A-Za-z0-9_]* { char msg[128];
- sprintf(msg, "unknown keyword %s", yytext);
- yyerror(msg);
- }
- <MIDI>. { char msg[128];
- sprintf(msg, "invalid character %s", yytext);
- yyerror(msg);
- }
- <CMNT>"*/" BEGIN MIDI;
- <CMNT>. ;
- <CMNT>\n src->linenr++;
-
- <PROGRAM>[ \t]+ ;
- <PROGRAM>\n src->linenr++;
- <PROGRAM>"$"{hexdigit}+ {
- yylval.longv = strtol(strchr((char*)yytext, '$')+1, 0, 16);
- BEGIN MIDI;
- return(_NUMBER);
- }
-
- <PROGRAM>"0[xX]"{hexdigit}+ {
- yylval.longv = strtol((char*)yytext+2, 0, 16);
- BEGIN MIDI;
- return(_NUMBER);
- }
-
- <PROGRAM>0[0-7]*/{eow} {
- yylval.longv = strtol(strchr((char*)yytext, '0'), 0, 8);
- BEGIN MIDI;
- return(_NUMBER);
- }
-
- <PROGRAM>[1-9][0-9]*/{eow} {
- yylval.longv = strtol((char*)yytext, 0, 10);
- BEGIN MIDI;
- return(_NUMBER);
- }
-
- <PROGRAM>[ABCD][1-8][1-8]/{eow} {
- yylval.longv = ((yytext[0] - 'A') % 2) * 64 + (yytext[1] - '1') * 8 + (yytext[2]-'1');
- BEGIN MIDI;
- return(_NUMBER);
- }
- <PROGRAM>[A-Za-z][A-Za-z0-9\.\-\!&]+/{eow} {
- int i, c;
- char msg[128];
-
- for (i = 0; i < 128; i++)
- for (c = 8; c <= 9; c++)
- if (STRICMP((char*)yytext, progname(i, c)) == 0)
- {
- BEGIN MIDI;
- yylval.longv = i;
- return(_NUMBER);
- }
-
- sprintf(msg, "invalid program name %s", yytext);
- yyerror(msg);
- }
-
- <PROGRAM>. {
- char msg[128];
-
- sprintf(msg, "invalid character %s", yytext);
- yyerror(msg);
- }
- %%
-
- int noteval(char* notename)
- {
- int level = 0;
- char* s = notename;
-
- s[0] = toupper(s[0]);
- switch(s[0])
- {
- case 'A': level = +9; break;
- case 'B':
- case 'H': level = +11; break;
- case 'C': level = 0; break;
- case 'D': level = 2; break;
- case 'E': level = 4; break;
- case 'F': level = 5; break;
- case 'G': level = 7; break;
- default: return -1;
- }
- s++;
- if (*s =='#')
- {
- level++;
- s++;
- }
- else if (strncmp(s, "is", 2) == 0)
- {
- level++;
- s+=2;
- }
- else if (*s == 'b' || *s == 's')
- {
- level--;
- s++;
- }
- else if (strncmp(s, "es", 2) == 0)
- {
- level--;
- s+=2;
- }
- if (*s == '-' || (*s >= '0' && *s <= '9'))
- level += 12 * (atoi(s)+1);
- else
- level += 12 * 5; // default octave is C4..B4
- if (level < 0 || level >= 128)
- {
- char msg[30];
-
- sprintf(msg, "note %s out of range C-1..C9", notename);
- yyerror(msg);
- level = 0;
- }
- return level;
- }
-
- int newfile(char* name)
- {
- int i;
-
- // add to table
- for (i = 0; i < filenames; i++)
- if (STRICMP(name, filename[i]) == 0)
- break;
- if (i == filenames)
- {
- strcpy(filename[i], name);
- filenames++;
- }
- src->index = i;
- src->linenr = 1;
- return i;
- }
-
- void includefile(char* includename)
- {
- FILE* f = fopen(includename, "rt");
-
- if (!f)
- {
- char msg[128];
-
- sprintf(msg, "cannot open include file %s", includename);
- yyerror(msg);
- }
- else
- {
- YY_BUFFER_STATE b;
- lexstate* inc = (lexstate*)malloc(sizeof(lexstate));
-
- b = yy_create_buffer( f, 512 );
-
- assert(inc != 0);
- init_lexstate(inc);
-
- inc->save = src;
-
- src->buffer = YY_CURRENT_BUFFER;
- yy_switch_to_buffer(b);
- inc->buffer = b;
-
- src = inc;
-
- printf("Including %s\n", includename);
- src->index = newfile(includename);
- }
- }
-
- int yylex(void)
- {
- int t;
-
- another:
- t = ylex();
-
- if (t == 0 && src->save != 0)
- {
- lexstate* save;
-
- // end of include
-
- save = src->save;
-
- yy_delete_buffer(YY_CURRENT_BUFFER);
- yy_switch_to_buffer(save->buffer);
-
- if (src) free(src);
- src = save;
- goto another;
- }
- return t;
- }
-
- void lexstart(char* name)
- {
- filenames = 0;
- src = (lexstate*)malloc(sizeof(lexstate));
- assert(src != 0);
- init_lexstate (src);
-
- printf("Compiling %s\n", name);
- src->index = newfile(name);
- src->linenr = 1;
- }
-
- long getlinenr()
- {
- return src->linenr;
- }
-
- int getsrcindex()
- {
- return src->index;
- }
-
- char* getsrcname( int index )
- {
- if (index >= 0 && index < filenames)
- return filename[index];
- return 0;
- }
-
- int srcfiles()
- {
- return filenames;
- }
-